package com.quickask.serviceImpl;

import com.quickask.common.Pager;
import com.quickask.dao.*;
import com.quickask.entity.*;
import com.quickask.operate.data.Constants;
import com.quickask.operate.data.ResultCode;
import com.quickask.operate.encode.Geohash;
import com.quickask.service.QuestionService;
import org.apache.log4j.Logger;
import org.json.JSONObject;

import java.sql.Timestamp;
import java.util.*;

/**
 * Created by NaSa on 2015/10/2.
 */
public class QuestionServiceImpl extends BaseServiceImpl implements QuestionService {

    private QuestionSetDao questionSetDao;
    private QuestionLocationSetDao questionLocationSetDao;
    private QuestionClassifyDao questionClassifyDao;
    private UserPrivilegeDao userPrivilegeDao;
    private AnswerSetDao answerSetDao;
    private UserDao userDao;
    protected Logger logger = Logger.getLogger(this.getClass());

    public void setQuestionSetDao(QuestionSetDao questionSetDao) {
        this.questionSetDao = questionSetDao;
    }

    public void setQuestionLocationSetDao(QuestionLocationSetDao questionLocationSetDao) {
        this.questionLocationSetDao = questionLocationSetDao;
    }

    public void setQuestionClassifyDao(QuestionClassifyDao questionClassifyDao) {
        this.questionClassifyDao = questionClassifyDao;
    }

    public void setUserPrivilegeDao(UserPrivilegeDao userPrivilegeDao) {
        this.userPrivilegeDao = userPrivilegeDao;
    }

    public void setAnswerSetDao(AnswerSetDao answerSetDao) {
        this.answerSetDao = answerSetDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    /**
     * 添加问题
     *
     * @param questionJson 问题相关内容，json格式
     * @param refreshToken 用户临时token
     * @return
     */
    @Override
    public AsknowQuestionSet addQuestion(String questionJson, String refreshToken) {
        try {
            JSONObject jsonObject = new JSONObject(questionJson);

            //AsknowQuestionSetEntity
            AsknowQuestionSetEntity asknowQuestionSetEntity = new AsknowQuestionSetEntity();
            asknowQuestionSetEntity.setUserId(jsonObject.optInt("userId"));
            asknowQuestionSetEntity.setQuestionAnswernum(0);
            asknowQuestionSetEntity.setQuestionAsknum(0);
            asknowQuestionSetEntity.setQuestionPoint(jsonObject.optInt("questionPoint"));
            asknowQuestionSetEntity.setQuestionDescription(jsonObject.optString("questionDescription"));
            asknowQuestionSetEntity.setQuestionContent(jsonObject.optString("questionContent"));
            asknowQuestionSetEntity.setQuestionIsAlived((byte) 1);
            asknowQuestionSetEntity.setQuestionIsSolved((byte) 0);
            asknowQuestionSetEntity.setQuestionAsktime(new Timestamp(System.currentTimeMillis()));


            questionSetDao.save(asknowQuestionSetEntity);
            //AsknowQuestionLocationSetEntity

            AsknowQuestionLocationSetEntity asknowQuestionLocationSetEntity = new AsknowQuestionLocationSetEntity();
            asknowQuestionLocationSetEntity.setQuestionId(asknowQuestionSetEntity.getQuestionId());
            asknowQuestionLocationSetEntity.setAltitude(jsonObject.optDouble("altitude"));
            asknowQuestionLocationSetEntity.setLongitude(jsonObject.optDouble("longitude"));
            asknowQuestionLocationSetEntity.setLatitude(jsonObject.optDouble("latitude"));
            asknowQuestionLocationSetEntity.setProvinceCode(jsonObject.optString("provinceCode"));
            asknowQuestionLocationSetEntity.setCityCode(jsonObject.optString("cityCode"));
            asknowQuestionLocationSetEntity.setBlockCode(jsonObject.optString("blockCode"));
            asknowQuestionLocationSetEntity.setLocationDetail(jsonObject.optString("locationDetail"));
            asknowQuestionLocationSetEntity.setGeohash(new Geohash().encode(jsonObject.optDouble("latitude"), jsonObject.optDouble("longitude")));
            asknowQuestionSetEntity.setAsknowQuestionLocationSetEntity(asknowQuestionLocationSetEntity);
            //questionLocationSetDao.save(asknowQuestionLocationSetEntity);

            //AsknowQuestionClassifyEntity
            AsknowQuestionClassifyEntity asknowQuestionClassifyEntity = new AsknowQuestionClassifyEntity();
            asknowQuestionClassifyEntity.setQuestionTag(jsonObject.optString("questionTag"));

            asknowQuestionClassifyEntity.setQuestionId(asknowQuestionSetEntity.getQuestionId());
            questionClassifyDao.save(asknowQuestionClassifyEntity);

            //return
            AsknowUserEntity asknowUserEntity = userDao.get(jsonObject.optInt("userId"));
            AsknowUserLocationEntity asknowUserLocationEntity = asknowUserEntity.getAsknowUserLocationEntity();
            if(asknowUserLocationEntity == null) {
                asknowUserLocationEntity = new AsknowUserLocationEntity();
            }
            asknowUserLocationEntity.setUserId(asknowUserEntity.getUserId());
            asknowUserLocationEntity.setAltitude(asknowQuestionLocationSetEntity.getAltitude());
            asknowUserLocationEntity.setLongitude(asknowQuestionLocationSetEntity.getLongitude());
            asknowUserLocationEntity.setLatitude(asknowQuestionLocationSetEntity.getLatitude());
            asknowUserLocationEntity.setProvinceCode(asknowQuestionLocationSetEntity.getProvinceCode());
            asknowUserLocationEntity.setCityCode(asknowQuestionLocationSetEntity.getCityCode());
            asknowUserLocationEntity.setBlockCode(asknowQuestionLocationSetEntity.getBlockCode());
            asknowUserLocationEntity.setLocationDetail(asknowQuestionLocationSetEntity.getLocationDetail());
            asknowUserLocationEntity.setGeohash(new Geohash().encode(asknowQuestionLocationSetEntity.getLatitude(), asknowQuestionLocationSetEntity.getLongitude()));

            asknowUserEntity.setAsknowUserLocationEntity(asknowUserLocationEntity);
            //saveOrUpdate
            //userDao.saveOrUpdate(asknowUserEntity);

            //jpush推送

            return setAsknowQuestionSet(asknowUserEntity.getAsknowUserPrivilegeEntity(),asknowQuestionSetEntity,null);
        } catch (Exception e) {
            logger.error("add question fail,due to " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 设置问题最佳答案
     *
     * @param questionId
     * @param answerId
     * @return
     */
    @Override
    public int addAdoptAnswer(int questionId, int answerId) {
        int result = 0;
        AsknowAnswerSetEntity asknowAnswerSetEntity = null;
        AsknowUserPrivilegeEntity asknowUserPrivilegeEntity = null;
        AsknowQuestionSetEntity asknowQuestionSetEntity = questionSetDao.get(questionId);
        if(asknowQuestionSetEntity.getQuestionIsSolved() == 0 && asknowQuestionSetEntity.getAnswerId()==null) {
            //设置最佳答案及状态为已解决
            //questionSetDao.addFavouriteAnswer(questionId,answerId);
            asknowAnswerSetEntity.setAnswerId(answerId);

            //设置答案已被采用
            asknowAnswerSetEntity = answerSetDao.get(answerId);
            asknowAnswerSetEntity.setAnswerIsAdopt((byte) 1);

            //增加用户积分
            asknowUserPrivilegeEntity = userPrivilegeDao.get(asknowAnswerSetEntity.getUserId());
            asknowUserPrivilegeEntity.setUserPoint(asknowUserPrivilegeEntity.getUserPoint()+asknowQuestionSetEntity.getQuestionPoint());
            return ResultCode.SUCCESS;
        }
        return ResultCode.QUESTION_ADOPT_ERROR;
    }

    /**
     * 添加问题同问数
     *
     * @param questionId
     * @param userId
     * @return
     */
    @Override
    public String updateQuestionAsknum(int questionId, int userId) {
        questionSetDao.updateQuestionAsknum(questionId);
        return null;
    }


    /**
     * 根据关键字查找问题
     *
     * @param pageNo     页码
     * @param pageSize   分页大小
     * @param text       搜索关键字
     * @param properties 其它参数
     * @return AsknowQuestionSet实体列表
     */
    @Override
    public List<AsknowQuestionSet> findQuestionListBySearch(int pageNo, int pageSize, String text, Map<String, Object> properties) {
        return null;
    }

    /**
     * @param pageNo    页码
     * @param pageSize  分页大小
     * @param properties 其它参数属性(latitude,longitude,blockCode...)
     * @return
     */
    @Override
    public List<AsknowQuestionSet> getQuestionListByAsktime(int pageNo, int pageSize, Map<String, Object> properties) {
        List<AsknowQuestionSet> asknowQuestionSetList = new ArrayList<AsknowQuestionSet>();
        Pager<AsknowQuestionSetEntity> pager = questionSetDao.getQuestionListOrderByAskTime(pageNo, pageSize, properties);
        for (AsknowQuestionSetEntity asknowQuestionSetEntity : pager.getPageRecords()) {
            AsknowQuestionSet asknowQuestionSet = setAsknowQuestionSet(userPrivilegeDao.get(asknowQuestionSetEntity.getUserId()),
                    asknowQuestionSetEntity, properties);
            asknowQuestionSetList.add(asknowQuestionSet);
        }
        return asknowQuestionSetList;
    }

    /**
     * @param pageNo     页码
     * @param pageSize   分页大小
     * @param properties 其它参数属性(latitude,longitude,blockCode...)
     * @return
     */
    @Override
    public List<AsknowQuestionSet> getQuestionListByGeohash(int pageNo, int pageSize, Map<String, Object> properties) {
        List<AsknowQuestionSet> asknowQuestionSets = new ArrayList<AsknowQuestionSet>();
        Pager<AsknowQuestionSetEntity> pagers = questionSetDao.getQuestionPagerByGeohash(pageNo, pageSize, properties);
        for(AsknowQuestionSetEntity asknowQuestionSetEntity:pagers.getPageRecords()) {
            AsknowQuestionSet asknowQuestionSet = setAsknowQuestionSet(userPrivilegeDao.get(asknowQuestionSetEntity.getUserId()),
                    asknowQuestionSetEntity ,properties);
            asknowQuestionSets.add(asknowQuestionSet);
        }
        return asknowQuestionSets;
    }


    /**
     * 获取用户的问题列表
     *
     * @param pageNo     页码
     * @param pageSize   页大小
     * @param userId     用户id
     * @param properties 其它参数属性(latitude,longitude...)
     * @return AsknowQuestionSet实体列表
     */
    @Override
    public List<AsknowQuestionSet> getQuestionListByUserId(int pageNo, int pageSize, int userId, Map<String, Object> properties) {
        List<AsknowQuestionSet> asknowQuestionSetList = new ArrayList<AsknowQuestionSet>();
        Pager<AsknowQuestionSetEntity> pager = questionSetDao.getQuestionListByUserId(pageNo, pageSize, userId);
        for (AsknowQuestionSetEntity asknowQuestionSetEntity : pager.getPageRecords()) {
            AsknowQuestionSet asknowQuestionSet = setAsknowQuestionSet(userPrivilegeDao.get(asknowQuestionSetEntity.getUserId()),
                    asknowQuestionSetEntity, properties);
            asknowQuestionSetList.add(asknowQuestionSet);
        }
        return asknowQuestionSetList;
    }




    /**
     * 按问题积分点获取问题列表分页
     *
     * @param pageNo     页码
     * @param pageSize   页大小
     * @param properties 其它参数属性(latitude,longitude...)
     * @return AsknowQuestionSet实体列表
     */
    @Override
    public List<AsknowQuestionSet> getQuestionListByQuestionPoint(int pageNo, int pageSize, Map<String, Object> properties) {
        List<AsknowQuestionSet> asknowQuestionSetList = new ArrayList<AsknowQuestionSet>();
        Pager<AsknowQuestionSetEntity> pager = questionSetDao.getQuestionListOrderByQuestionPoint(pageNo, pageSize, properties);
        for (AsknowQuestionSetEntity asknowQuestionSetEntity : pager.getPageRecords()) {
            AsknowQuestionSet asknowQuestionSet = setAsknowQuestionSet(userPrivilegeDao.get(asknowQuestionSetEntity.getUserId()),
                    asknowQuestionSetEntity, properties);
            asknowQuestionSetList.add(asknowQuestionSet);
        }
        return asknowQuestionSetList;
    }
//    @Override
//    public List<AsknowQuestionSet> getQuestionListByQuestionPoint(int pageNo, int pageSize, Map<String, Object> properties) {
//        List<AsknowQuestionSet> asknowQuestionSetList = new ArrayList<AsknowQuestionSet>();
//
//        Iterator iterator = questionSetDao.getQuestionListOrderByQuestionPoint(pageNo, pageSize, properties).iterator();
//        while (iterator.hasNext()) {
//            Object[] obj = (Object[]) iterator.next();
//            AsknowQuestionSet asknowQuestionSet = new AsknowQuestionSet();
//            asknowQuestionSet.setQuestionId(obj[0]==null?null:Integer.valueOf(obj[0].toString()));
//            asknowQuestionSet.setQuestionAsktime(obj[1]==null?null:Timestamp.valueOf(obj[1].toString()));
//            asknowQuestionSet.setQuestionAsknum(obj[2]==null?null:Integer.valueOf(obj[2].toString()));
//            asknowQuestionSet.setQuestionAnswernum(obj[3]==null?null:Integer.valueOf(obj[3].toString()));
//            asknowQuestionSet.setQuestionContent(obj[4]==null?null:obj[4].toString());
//            asknowQuestionSet.setUserId(obj[5]==null?null:Integer.valueOf(obj[5].toString()));
//            asknowQuestionSet.setAnswerId(obj[6]==null?null:Integer.valueOf(obj[6].toString()));
//            asknowQuestionSet.setQuestionPoint(obj[7]==null?null:Integer.valueOf(obj[7].toString()));
//            asknowQuestionSet.setQuestionIsSolved(obj[8]==null?null:Byte.parseByte(obj[8].toString()));
//            asknowQuestionSet.setQuestionIsAlived(obj[9]==null?null:Byte.parseByte(obj[9].toString()));
//            asknowQuestionSet.setQuestionImageUrls(obj[10]==null?null:obj[10].toString());
//            asknowQuestionSet.setQuestionVoiceUrls(obj[11]==null?null:obj[11].toString());
//            asknowQuestionSet.setQuestionDescription(obj[12]==null?null:obj[12].toString());
//            asknowQuestionSet.setLocationDetail(obj[16]==null?null:obj[16].toString());
//            //计算距离
//            if (null != properties && properties.containsKey("latitude")) {
//                asknowQuestionSet.setDistance(Constants.computeDistance(Double.parseDouble(obj[14].toString()),Double.parseDouble(obj[13].toString()),(Double)properties.get("latitude"),
//                        (Double)properties.get("longitude")));
//            } else {
//                asknowQuestionSet.setDistance(0.0d);
//            }
//            //设置最佳答案内容
//            String answerContent = obj[6]==null?null:answerSetDao.get(Integer.valueOf(obj[6].toString())).getAnswerContent();
//            asknowQuestionSet.setAnswerContent(answerContent);
//            AsknowUserPrivilegeEntity asknowUserPrivilegeEntity = userPrivilegeDao.get(Integer.valueOf(obj[5].toString()));
//            asknowQuestionSet.setUserNickname(asknowUserPrivilegeEntity.getUserNickname());
//            asknowQuestionSet.setUserIcon(asknowUserPrivilegeEntity.getUserIcon());
//            asknowQuestionSetList.add(asknowQuestionSet);
//
//            LinkedHashMap<String, Object> map = (LinkedHashMap<String, Object>) iterator.next();
//            System.out.println("结果集："+map.get("questionContent"));
//        }
//        return asknowQuestionSetList;
//    }

    /**
     * 按同问数获取问题列表分页
     *
     * @param pageNo     页码
     * @param pageSize   页大小
     * @param properties 其它参数属性(latitude,longitude,blockCode...)
     * @return AsknowQuestionSet实体列表
     */
    @Override
    public List<AsknowQuestionSet> getQuestionListByAnswernum(int pageNo, int pageSize, Map<String, Object> properties) {
        List<AsknowQuestionSet> asknowQuestionSetList = new ArrayList<AsknowQuestionSet>();
        Pager<AsknowQuestionSetEntity> pager = questionSetDao.getQuestionPagerOrderByAnswernum(pageNo, pageSize,properties);
        for (AsknowQuestionSetEntity asknowQuestionSetEntity : pager.getPageRecords()) {
            AsknowQuestionSet asknowQuestionSet = setAsknowQuestionSet(userPrivilegeDao.get(asknowQuestionSetEntity.getUserId()),
                    asknowQuestionSetEntity, properties);
            asknowQuestionSetList.add(asknowQuestionSet);
        }
        return asknowQuestionSetList;
    }

    /**
     * 按回答数获取问题列表分页
     *
     * @param pageNo     页码
     * @param pageSize   页大小
     * @param properties 其它参数属性(latitude,longitude,blockCode...)
     * @return AsknowQuestionSet实体列表
     */
    @Override
    public List<AsknowQuestionSet> getQuestionListByAsknum(int pageNo, int pageSize, Map<String, Object> properties) {
        List<AsknowQuestionSet> asknowQuestionSetList = new ArrayList<AsknowQuestionSet>();
        Pager<AsknowQuestionSetEntity> pager = questionSetDao.getQuestionPagerByAsknum(pageNo, pageSize,properties);
        for (AsknowQuestionSetEntity asknowQuestionSetEntity : pager.getPageRecords()) {
            AsknowQuestionSet asknowQuestionSet = setAsknowQuestionSet(userPrivilegeDao.get(asknowQuestionSetEntity.getUserId()),
                    asknowQuestionSetEntity, properties);
            asknowQuestionSetList.add(asknowQuestionSet);
        }
        return asknowQuestionSetList;
    }

    /**
     * 按问题类别获取问题列表分页
     *
     * @param pageNo       页码
     * @param pageSize     页大小
     * @param classifyName 类别名
     * @param properties   其它参数属性(latitude,longitude...)
     * @return AsknowQuestionSet实体列表
     */
    @Override
    public List<AsknowQuestionSet> findQuestionPagerByQuestionClassify(int pageNo, int pageSize, String classifyName, Map<String, Object> properties) {
        List<AsknowQuestionSet> asknowQuestionSetList = new ArrayList<AsknowQuestionSet>();
        Pager<AsknowQuestionClassifyEntity> pager = questionClassifyDao.findQuestionPagerByQuestionClassify(pageNo, pageSize, classifyName);
        for (AsknowQuestionClassifyEntity asknowQuestionClassifyEntity : pager.getPageRecords()) {
            AsknowQuestionSetEntity asknowQuestionSetEntity = questionSetDao.get(asknowQuestionClassifyEntity.getQuestionId());
            AsknowQuestionSet asknowQuestionSet = setAsknowQuestionSet(userPrivilegeDao.get(asknowQuestionSetEntity.getUserId()),
                    asknowQuestionSetEntity, properties);
            asknowQuestionSetList.add(asknowQuestionSet);
        }
        return asknowQuestionSetList;
    }

    //设置asknowQuestionSet实体并返回
    public AsknowQuestionSet setAsknowQuestionSet(AsknowUserPrivilegeEntity asknowUserPrivilegeEntity, AsknowQuestionSetEntity asknowQuestionSetEntity, Map<String, Object> properties) {
        AsknowQuestionSet asknowQuestionSet = new AsknowQuestionSet();
        asknowQuestionSet.setUserNickname(asknowUserPrivilegeEntity.getUserNickname());
        asknowQuestionSet.setUserIcon(asknowUserPrivilegeEntity.getUserIcon());
        asknowQuestionSet.setUserId(asknowQuestionSetEntity.getUserId());
        asknowQuestionSet.setQuestionId(asknowQuestionSetEntity.getQuestionId());
        asknowQuestionSet.setQuestionAsktime(asknowQuestionSetEntity.getQuestionAsktime());
        asknowQuestionSet.setQuestionAsknum(asknowQuestionSetEntity.getQuestionAsknum());
        asknowQuestionSet.setQuestionAnswernum(asknowQuestionSetEntity.getQuestionAnswernum());
        asknowQuestionSet.setQuestionContent(asknowQuestionSetEntity.getQuestionContent());
        asknowQuestionSet.setQuestionDescription(asknowQuestionSetEntity.getQuestionDescription());
        asknowQuestionSet.setAnswerId(asknowQuestionSetEntity.getAnswerId());
        asknowQuestionSet.setQuestionIsSolved(asknowQuestionSetEntity.getQuestionIsSolved());
        asknowQuestionSet.setQuestionIsAlived(asknowQuestionSetEntity.getQuestionIsAlived());
        asknowQuestionSet.setQuestionPoint(asknowQuestionSetEntity.getQuestionPoint());
        asknowQuestionSet.setQuestionImageUrls(asknowQuestionSetEntity.getQuestionImageUrls());
        asknowQuestionSet.setQuestionVoiceUrls(asknowQuestionSetEntity.getQuestionVoiceUrls());
        asknowQuestionSet.setLocationDetail(asknowQuestionSetEntity.getAsknowQuestionLocationSetEntity().getLocationDetail());

        //计算距离
        if (null != properties && properties.containsKey("latitude")) {
            asknowQuestionSet.setDistance(Constants.computeDistance((Double) properties.get("latitude"), (Double) properties.get("longitude"), asknowQuestionSetEntity.getAsknowQuestionLocationSetEntity().getLatitude(),
                    asknowQuestionSetEntity.getAsknowQuestionLocationSetEntity().getLongitude()));
        } else {
            asknowQuestionSet.setDistance(0.0d);
        }
        //设置最佳答案内容
        String answerContent = asknowQuestionSetEntity.getAnswerId()==null?null:answerSetDao.get(asknowQuestionSetEntity.getAnswerId()).getAnswerContent();
        asknowQuestionSet.setAnswerContent(answerContent);
        return asknowQuestionSet;
    }

    public List<AsknowUQL> getAsknowQuestionLocationList(Pager<AsknowQuestionSetEntity> pager, Map<String, Object> properties) {
        List<AsknowUQL> asknowUQLs = new ArrayList<AsknowUQL>();
        for (AsknowQuestionSetEntity asknowQuestionSetEntity : pager.getPageRecords()) {
            AsknowUQL asknowUQL = new AsknowUQL();
            asknowUQL.setAsknowQuestionSetEntity(asknowQuestionSetEntity);
            asknowUQL.setAsknowQuestionLocationSetEntity(questionLocationSetDao.get(asknowQuestionSetEntity.getQuestionId()));
            asknowUQL.setDistance(0.1d);
            asknowUQLs.add(asknowUQL);
        }
        return asknowUQLs;
    }
}
